<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="Generator" content="Kate, the KDE Advanced Text Editor" />
<title>tutorial8.py</title>
</head>
<body>
<pre style='color:#141312;background-color:#ffffff;'>
<i><span style='color:#008000;'>#!/usr/bin/env python</span></i>

<i><span style='color:#008000;'>&quot;&quot;&quot;********************************************************************************</span></i>
<i><span style='color:#008000;'>                             tutorial8.py</span></i>
<i><span style='color:#008000;'>                 DAE Tools: pyDAE module, www.daetools.com</span></i>
<i><span style='color:#008000;'>                 Copyright (C) Dragan Nikolic, 2010</span></i>
<i><span style='color:#008000;'>***********************************************************************************</span></i>
<i><span style='color:#008000;'>DAE Tools is free software; you can redistribute it and/or modify it under the </span></i>
<i><span style='color:#008000;'>terms of the GNU General Public License as published by the Free Software </span></i>
<i><span style='color:#008000;'>Foundation; either version 3 of the License, or (at your option) any later version.</span></i>
<i><span style='color:#008000;'>The DAE Tools is distributed in the hope that it will be useful, but WITHOUT ANY </span></i>
<i><span style='color:#008000;'>WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A </span></i>
<i><span style='color:#008000;'>PARTICULAR PURPOSE. See the GNU General Public License for more details.</span></i>
<i><span style='color:#008000;'>You should have received a copy of the GNU General Public License along with the</span></i>
<i><span style='color:#008000;'>DAE Tools software; if not, write to the Free Software Foundation, Inc., </span></i>
<i><span style='color:#008000;'>59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.</span></i>
<i><span style='color:#008000;'>********************************************************************************&quot;&quot;&quot;</span></i>

<i><span style='color:#008000;'>&quot;&quot;&quot;</span></i>
<i><span style='color:#008000;'>In this example we use a similar problem as in the tutorial 5.</span></i>
<i><span style='color:#008000;'>Here we introduce:</span></i>
<i><span style='color:#008000;'> - Custom data reporters</span></i>

<i><span style='color:#008000;'>Some time it is not enough to send the result to daePlotter but it is desirable to </span></i>
<i><span style='color:#008000;'>export them in certain format for use in other programs. Here we show how the custom</span></i>
<i><span style='color:#008000;'>data reporter can be created. In this example the data reporter simply, after the simulation</span></i>
<i><span style='color:#008000;'>is finished, save the results into a plain text file. Obviously, the data can be exported to</span></i>
<i><span style='color:#008000;'>any format. Also some numpy functions that operate on numpy arrays can be used as well.</span></i>
<i><span style='color:#008000;'>In addition, a new type of data reporters (daeDelegateDataReporter) is presented. It</span></i>
<i><span style='color:#008000;'>has the same interface and the functionality like all data reporters. However, it does not do</span></i>
<i><span style='color:#008000;'>any data processing by itself but calls the corresponding functions of data reporters which </span></i>
<i><span style='color:#008000;'>are added to it by using the function AddDataReporter. This way it is possible, at the same </span></i>
<i><span style='color:#008000;'>time, to send the results to the daePlotter and save them into a file (or process them in</span></i>
<i><span style='color:#008000;'>some other ways). </span></i>
<i><span style='color:#008000;'>&quot;&quot;&quot;</span></i>

<span style='color:#0000ff;'>import</span> sys
<span style='color:#0000ff;'>from</span> daetools.pyDAE <span style='color:#0000ff;'>import</span> <span style='color:#0000ff;'>*</span>
<span style='color:#0000ff;'>from</span> time <span style='color:#0000ff;'>import</span> localtime, strftime

typeNone         <span style='color:#0000ff;'>=</span> daeVariableType(<span style='color:#bf0303;'>&quot;None&quot;</span>,         <span style='color:#bf0303;'>&quot;-&quot;</span>,      <span style='color:#c000c0;'>0</span>, <span style='color:#c000c0;'>1E10</span>,   <span style='color:#c000c0;'>0</span>, <span style='color:#c000c0;'>1e-5</span>)
typeTemperature  <span style='color:#0000ff;'>=</span> daeVariableType(<span style='color:#bf0303;'>&quot;Temperature&quot;</span>,  <span style='color:#bf0303;'>&quot;K&quot;</span>,    <span style='color:#c000c0;'>100</span>, <span style='color:#c000c0;'>1000</span>, <span style='color:#c000c0;'>300</span>, <span style='color:#c000c0;'>1e-5</span>)
typeConductivity <span style='color:#0000ff;'>=</span> daeVariableType(<span style='color:#bf0303;'>&quot;Conductivity&quot;</span>, <span style='color:#bf0303;'>&quot;W/mK&quot;</span>,   <span style='color:#c000c0;'>0</span>, <span style='color:#c000c0;'>1E10</span>, <span style='color:#c000c0;'>100</span>, <span style='color:#c000c0;'>1e-5</span>)
typeDensity      <span style='color:#0000ff;'>=</span> daeVariableType(<span style='color:#bf0303;'>&quot;Density&quot;</span>,      <span style='color:#bf0303;'>&quot;kg/m3&quot;</span>,  <span style='color:#c000c0;'>0</span>, <span style='color:#c000c0;'>1E10</span>, <span style='color:#c000c0;'>100</span>, <span style='color:#c000c0;'>1e-5</span>)
typeHeatCapacity <span style='color:#0000ff;'>=</span> daeVariableType(<span style='color:#bf0303;'>&quot;HeatCapacity&quot;</span>, <span style='color:#bf0303;'>&quot;J/KgK&quot;</span>,  <span style='color:#c000c0;'>0</span>, <span style='color:#c000c0;'>1E10</span>, <span style='color:#c000c0;'>100</span>, <span style='color:#c000c0;'>1e-5</span>)

<i><span style='color:#008000;'># The best starting point in creating custom data reporters that can export the results </span></i>
<i><span style='color:#008000;'># into a file is daeDataReporterLocal class. It internally does all the processing</span></i>
<i><span style='color:#008000;'># and offers a user the Process property of type daeDataReporterProcess which contains</span></i>
<i><span style='color:#008000;'># all domains and variables sent by simulation. The following functions have to be implemented:</span></i>
<i><span style='color:#008000;'>#  - Connect</span></i>
<i><span style='color:#008000;'>#    It is used to connect the data reporter. In the case when the local data reporter is used</span></i>
<i><span style='color:#008000;'>#    it may contain a file name, for instance.</span></i>
<i><span style='color:#008000;'>#  - Disconnect</span></i>
<i><span style='color:#008000;'>#    Disconnects the data reporter.</span></i>
<i><span style='color:#008000;'>#  - IsConnected</span></i>
<i><span style='color:#008000;'>#    Check if the data reporter is connected or not.</span></i>
<i><span style='color:#008000;'># In this example we use the first argument of the function Connect as a file name to open </span></i>
<i><span style='color:#008000;'># a text file and implement a new function Write to write the data into the file.</span></i>
<i><span style='color:#008000;'># In the function Write we iterate over all variables and write their values into a file.</span></i>
<b>class</b> MyDataReporter(daeDataReporterLocal):
    <b>def</b> <b><span style='color:#000e52;'>__init__</span></b>(<span style='color:#0000ff;'>self</span>):
        daeDataReporterLocal.<b><span style='color:#000e52;'>__init__</span></b>(<span style='color:#0000ff;'>self</span>)

    <b>def</b> Connect(<span style='color:#0000ff;'>self</span>, ConnectionString, ProcessName):
        <span style='color:#0000ff;'>self</span>.ProcessName <span style='color:#0000ff;'>=</span> ProcessName
        <b>try</b>:
            <span style='color:#0000ff;'>self</span>.f <span style='color:#0000ff;'>=</span> <b><span style='color:#000000;'>open</span></b>(ConnectionString, <span style='color:#bf0303;'>&quot;w&quot;</span>)            
        <b>except</b> <b><span style='color:#054d00;'>IOError</span></b>:
            <b>return</b> <span style='color:#0000ff;'>False</span>       
        <b>return</b> <span style='color:#0000ff;'>True</span>
        
    <b>def</b> Disconnect(<span style='color:#0000ff;'>self</span>):
        <b>return</b> <span style='color:#0000ff;'>True</span>

    <b>def</b> Write(<span style='color:#0000ff;'>self</span>):
        <b>try</b>:
            <span style='color:#0000ff;'>self</span>.f.write(<span style='color:#bf0303;'>&quot;Process name: &quot;</span> <span style='color:#0000ff;'>+</span> <span style='color:#0000ff;'>self</span>.ProcessName <span style='color:#0000ff;'>+</span> <span style='color:#bf0303;'>&quot;</span><span style='color:#ff80e0;'>\n</span><span style='color:#bf0303;'>&quot;</span>)
            variables <span style='color:#0000ff;'>=</span> <span style='color:#0000ff;'>self</span>.Process.Variables
            <b>for</b> var <span style='color:#0000ff;'>in</span> variables:
                values  <span style='color:#0000ff;'>=</span> var.Values
                domains <span style='color:#0000ff;'>=</span> var.Domains
                times   <span style='color:#0000ff;'>=</span> var.TimeValues
                <span style='color:#0000ff;'>self</span>.f.write(<span style='color:#bf0303;'>&quot; - Variable: &quot;</span> <span style='color:#0000ff;'>+</span> var.Name <span style='color:#0000ff;'>+</span> <span style='color:#bf0303;'>&quot;</span><span style='color:#ff80e0;'>\n</span><span style='color:#bf0303;'>&quot;</span>)
                <span style='color:#0000ff;'>self</span>.f.write(<span style='color:#bf0303;'>&quot;    - Domains:&quot;</span> <span style='color:#0000ff;'>+</span> <span style='color:#bf0303;'>&quot;</span><span style='color:#ff80e0;'>\n</span><span style='color:#bf0303;'>&quot;</span>)
                <b>for</b> domain <span style='color:#0000ff;'>in</span> domains:
                    <span style='color:#0000ff;'>self</span>.f.write(<span style='color:#bf0303;'>&quot;       - &quot;</span> <span style='color:#0000ff;'>+</span> domain.Name <span style='color:#0000ff;'>+</span> <span style='color:#bf0303;'>&quot;</span><span style='color:#ff80e0;'>\n</span><span style='color:#bf0303;'>&quot;</span>)
                <span style='color:#0000ff;'>self</span>.f.write(<span style='color:#bf0303;'>&quot;    - Values:&quot;</span> <span style='color:#0000ff;'>+</span> <span style='color:#bf0303;'>&quot;</span><span style='color:#ff80e0;'>\n</span><span style='color:#bf0303;'>&quot;</span>)
                <b>for</b> i <span style='color:#0000ff;'>in</span> <b><span style='color:#000000;'>range</span></b>(<b><span style='color:#000000;'>len</span></b>(times)):
                    <span style='color:#0000ff;'>self</span>.f.write(<span style='color:#bf0303;'>&quot;      - Time: &quot;</span> <span style='color:#0000ff;'>+</span> <b><span style='color:#000000;'>str</span></b>(times[i]) <span style='color:#0000ff;'>+</span> <span style='color:#bf0303;'>&quot;</span><span style='color:#ff80e0;'>\n</span><span style='color:#bf0303;'>&quot;</span>)
                    <span style='color:#0000ff;'>self</span>.f.write(<span style='color:#bf0303;'>&quot;        &quot;</span> <span style='color:#0000ff;'>+</span> <b><span style='color:#000000;'>str</span></b>(values[i, ...]) <span style='color:#0000ff;'>+</span> <span style='color:#bf0303;'>&quot;</span><span style='color:#ff80e0;'>\n</span><span style='color:#bf0303;'>&quot;</span>)

            <span style='color:#0000ff;'>self</span>.f.close()

        <b>except</b> <b><span style='color:#054d00;'>IOError</span></b>:
            <span style='color:#0000ff;'>self</span>.f.close()
            <b>return</b> <span style='color:#0000ff;'>False</span>
        
    <b>def</b> IsConnected(<span style='color:#0000ff;'>self</span>):
        <b>return</b> <span style='color:#0000ff;'>True</span>

<b>class</b> modTutorial(daeModel):
    <b>def</b> <b><span style='color:#000e52;'>__init__</span></b>(<span style='color:#0000ff;'>self</span>, Name, Parent <span style='color:#0000ff;'>=</span> <span style='color:#0000ff;'>None</span>, Description <span style='color:#0000ff;'>=</span> <span style='color:#bf0303;'>&quot;&quot;</span>):
        daeModel.<b><span style='color:#000e52;'>__init__</span></b>(<span style='color:#0000ff;'>self</span>, Name, Parent, Description)

        <span style='color:#0000ff;'>self</span>.Qin  <span style='color:#0000ff;'>=</span> daeParameter(<span style='color:#bf0303;'>&quot;Q_in&quot;</span>, eReal, <span style='color:#0000ff;'>self</span>, <span style='color:#bf0303;'>&quot;Power of the heater, W&quot;</span>)

        <span style='color:#0000ff;'>self</span>.m  <span style='color:#0000ff;'>=</span> daeParameter(<span style='color:#bf0303;'>&quot;m&quot;</span>,   eReal, <span style='color:#0000ff;'>self</span>, <span style='color:#bf0303;'>&quot;Mass of the plate, kg&quot;</span>)
        <span style='color:#0000ff;'>self</span>.cp <span style='color:#0000ff;'>=</span> daeParameter(<span style='color:#bf0303;'>&quot;c_p&quot;</span>, eReal, <span style='color:#0000ff;'>self</span>, <span style='color:#bf0303;'>&quot;Specific heat capacity of the plate, J/kgK&quot;</span>)
 
        <span style='color:#0000ff;'>self</span>.T <span style='color:#0000ff;'>=</span> daeVariable(<span style='color:#bf0303;'>&quot;T&quot;</span>, typeTemperature, <span style='color:#0000ff;'>self</span>, <span style='color:#bf0303;'>&quot;Temperature of the plate, K&quot;</span>)

    <b>def</b> DeclareEquations(<span style='color:#0000ff;'>self</span>):
        eq <span style='color:#0000ff;'>=</span> <span style='color:#0000ff;'>self</span>.CreateEquation(<span style='color:#bf0303;'>&quot;HeatBalance&quot;</span>, <span style='color:#bf0303;'>&quot;Integral heat balance equation.&quot;</span>)
        eq.Residual <span style='color:#0000ff;'>=</span> <span style='color:#0000ff;'>self</span>.m() <span style='color:#0000ff;'>*</span> <span style='color:#0000ff;'>self</span>.cp() <span style='color:#0000ff;'>*</span> <span style='color:#0000ff;'>self</span>.T.dt() <span style='color:#0000ff;'>-</span> <span style='color:#0000ff;'>self</span>.Qin()

<b>class</b> simTutorial(daeDynamicSimulation):
    <b>def</b> <b><span style='color:#000e52;'>__init__</span></b>(<span style='color:#0000ff;'>self</span>):
        daeDynamicSimulation.<b><span style='color:#000e52;'>__init__</span></b>(<span style='color:#0000ff;'>self</span>)
        <span style='color:#0000ff;'>self</span>.m <span style='color:#0000ff;'>=</span> modTutorial(<span style='color:#bf0303;'>&quot;Tutorial_8&quot;</span>)
        <span style='color:#0000ff;'>self</span>.m.Description <span style='color:#0000ff;'>=</span> <span style='color:#bf0303;'>&quot;This tutorial explains how to create custom data reporters and how to create a composite data reporter which delegates &quot;</span> <span style='color:#0000ff;'>\</span>
                             <span style='color:#bf0303;'>&quot;the data processing to other data reporters. &quot;</span>
          
    <b>def</b> SetUpParametersAndDomains(<span style='color:#0000ff;'>self</span>):
        <span style='color:#0000ff;'>self</span>.m.cp.SetValue(<span style='color:#c000c0;'>385</span>)
        <span style='color:#0000ff;'>self</span>.m.m.SetValue(<span style='color:#c000c0;'>1</span>)
        <span style='color:#0000ff;'>self</span>.m.Qin.SetValue(<span style='color:#c000c0;'>500</span>)

    <b>def</b> SetUpVariables(<span style='color:#0000ff;'>self</span>):
        <span style='color:#0000ff;'>self</span>.m.T.SetInitialCondition(<span style='color:#c000c0;'>300</span>)

<b>if</b> <b><span style='color:#000000;'>__name__</span></b> <span style='color:#0000ff;'>==</span> <span style='color:#bf0303;'>&quot;__main__&quot;</span>:
    <i><span style='color:#008000;'># Create Log, Solver, DataReporter and Simulation object</span></i>
    log          <span style='color:#0000ff;'>=</span> daePythonStdOutLog()
    solver       <span style='color:#0000ff;'>=</span> daeIDASolver()
    simulation   <span style='color:#0000ff;'>=</span> simTutorial()

    <i><span style='color:#008000;'># Create daeDelegateDataReporter and the add 2 data reporters:</span></i>
    <i><span style='color:#008000;'># - MyDataReporterLocal (to write data to the file 'tutorial8.out')</span></i>
    <i><span style='color:#008000;'># - daeTCPIPDataReporter (to send data to the daePlotter)</span></i>
    datareporter <span style='color:#0000ff;'>=</span> daeDelegateDataReporter()
    dr1 <span style='color:#0000ff;'>=</span> MyDataReporter()
    dr2 <span style='color:#0000ff;'>=</span> daeTCPIPDataReporter()
    datareporter.AddDataReporter(dr1)
    datareporter.AddDataReporter(dr2)

    <i><span style='color:#008000;'># Enable reporting of all variables</span></i>
    simulation.m.SetReportingOn(<span style='color:#0000ff;'>True</span>)

    <i><span style='color:#008000;'># Set the time horizon and the reporting interval</span></i>
    simulation.ReportingInterval <span style='color:#0000ff;'>=</span> <span style='color:#c000c0;'>10</span>
    simulation.TimeHorizon <span style='color:#0000ff;'>=</span> <span style='color:#c000c0;'>100</span>

    <i><span style='color:#008000;'># Connect data reporter</span></i>
    simName <span style='color:#0000ff;'>=</span> simulation.m.Name <span style='color:#0000ff;'>+</span> strftime(<span style='color:#bf0303;'>&quot; [</span><span style='color:#0000ff;'>%d</span><span style='color:#bf0303;'>.%m.%Y %H:%M:%S]&quot;</span>, localtime())
    <b>if</b>(dr1.Connect(<span style='color:#bf0303;'>&quot;tutorial8.out&quot;</span>, simName) <span style='color:#0000ff;'>==</span> <span style='color:#0000ff;'>False</span>):
        sys.exit()
    <b>if</b>(dr2.Connect(<span style='color:#bf0303;'>&quot;&quot;</span>, simName) <span style='color:#0000ff;'>==</span> <span style='color:#0000ff;'>False</span>):
        sys.exit()

    <i><span style='color:#008000;'># Initialize the simulation</span></i>
    simulation.Initialize(solver, datareporter, log)

    <i><span style='color:#008000;'># Save the model report and the runtime model report </span></i>
    simulation.m.SaveModelReport(simulation.m.Name <span style='color:#0000ff;'>+</span> <span style='color:#bf0303;'>&quot;.xml&quot;</span>)
    simulation.m.SaveRuntimeModelReport(simulation.m.Name <span style='color:#0000ff;'>+</span> <span style='color:#bf0303;'>&quot;-rt.xml&quot;</span>)

    <i><span style='color:#008000;'># Solve at time=0 (initialization)</span></i>
    simulation.SolveInitial()

    <i><span style='color:#008000;'># Run</span></i>
    simulation.Run()

    <i><span style='color:#008000;'># Finally, write the data to a file</span></i>
    dr1.Write()
</pre>
</body>
</html>
